package com.cennavi.mineplay.mineplay_data.model.transform.inter.impl;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cennavi.mineplay.mineplay_data.bean.AddPointBean;
import com.cennavi.mineplay.mineplay_data.bean.AddPointBean.FeaturesBean;
import com.cennavi.mineplay.mineplay_data.bean.LinkBean;
import com.cennavi.mineplay.mineplay_data.bean.LinkInfoBean;
import com.cennavi.mineplay.mineplay_data.bean.RedisConfigBean;
import com.cennavi.mineplay.mineplay_data.model.transform.inter.Transform;
import com.cennavi.mineplay.mineplay_data.redis.RedisUtil;
import com.cennavi.mineplay.mineplay_data.utils.LineMergeImp;
import com.cennavi.mineplay.mineplay_data.utils.RouteInterface;
import com.cennavi.mineplay.mineplay_data.utils.Tools;
import com.navinfo.mapspotter.foundation.io.IOUtil;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
@Configuration
public class AddPointTransformImpl implements Transform {
	@Autowired
    private RedisConfigBean configBean;
    private RedisUtil linkUtil;
    
    //补点的级别
    private int leavel;
    public AddPointTransformImpl(){
    	
    }
    public AddPointTransformImpl(int leavel) {      
        this.leavel=leavel;
    }
	@Override
	public void trans(JSONObject tp,int leavel) {
		//参数判空
		if(tp == null){
			return;
		}
		linkUtil = new RedisUtil(configBean);
		//将json对象转为JavaBean
		AddPointBean tpBean=(AddPointBean) JSONObject.toJavaObject(tp, AddPointBean.class);
		JSONArray  pointArray=new JSONArray();
		//javaBean对象判断
        if(tpBean != null){
        	List<FeaturesBean> list=tpBean.getFeatures();	
        	//若传入的点数目小于2
        	if(list == null ||list.size()<=0){
        		tp=null;
        		return;
        	}
        	if(list.size()==1){
			    JSONObject pointMsg=new JSONObject();
//			    pointMsg.put("carId","1");
			    pointMsg.put("speed",list.get(0).getProperties().getSpeed());	
			    pointMsg.put("time",list.get(0).getProperties().getTime());
    			String poointMsg= "["+ list.get(0).getGeometry().getCoordinates().get(0)+","+list.get(0).getGeometry().getCoordinates().get(1)+","+1+","+0+"]";
    		    pointMsg.put("point",JSON.parseArray(poointMsg));
    			pointArray.add(pointMsg);	
    			tp.clear();
    	     	tp.put("data", pointArray);
    	     	return;
        	}
        	
        	
        	//循环两两补点
        	for(int index=list.size()-1;index>=0;index--){
        		if(index-1 >=0){
        			List<FeaturesBean> locationList =new ArrayList<FeaturesBean>();
        			locationList.add(list.get(index));
        			locationList.add(list.get(index-1));
        			JSONArray jsonArray=new JSONArray();
                	String lineMsg="";	
                	//拼接推测接口参数
                	for(int i=0;i<locationList.size();i++){
                		double lat=locationList.get(i).getGeometry().getCoordinates().get(1);
                		double lon=locationList.get(i).getGeometry().getCoordinates().get(0);
                		String gpsTimeStr=locationList.get(i).getProperties().getTime()+"";
                		long gpsTime=dateToStamp(gpsTimeStr);
                		DecimalFormat df = new DecimalFormat("0.0000000");
                		df.format(lat);
                		df.format(lon);
                		String latStr=(int)(lat*10000000)+"";
                		String lonStr=(int)(lon*10000000)+"";
                		int time=(int)(gpsTime/1000);
                		lineMsg=lineMsg+"{\"deviceID\":\""+1+"\",\"gpstime\":"+time+",\"longitude\":"+lonStr+",\"speed\":"+(int)locationList.get(i).getProperties().getSpeed()+",\"heading\":"+(int)locationList.get(i).getProperties().getDirect()+",\"latitude\":"+latStr+"},";
                 		
                	}
                	String linkIdMsg="["+lineMsg.substring(0,lineMsg.length()-1)+"]";
                	//访问路径推测接口
                	String linkMsgJson =
                            RouteInterface
                                    .sendPost2(
                                            configBean.getUrl(),
                                            linkIdMsg);
                	//路径推测接口返回结果判断
                	if(linkMsgJson != null && !linkMsgJson.equals("")){
        	        	String responseBody = JSONObject.parseObject(linkMsgJson).getString("responseBody").toString();
        	        	String json = new String(Tools.uncompress(Base64.getDecoder().decode(responseBody.getBytes())));
        	        	if(json != null && !json.equals("")){
        	        		JSONArray array = JSONArray.parseArray(json);
        	        		if(array != null && array.size()>0){
        	        			JSONArray traArray=(JSONArray)array.getJSONObject(0).get("trajectory");
        	        			if(traArray !=null && traArray.size()>0){
        	        		     List<LineString> cutList = new ArrayList<LineString>();
        	        	         LineMergeImp lineMerger = new LineMergeImp();
        			        	for(int i=0;i<traArray.size();i++){
        			        		//通过LinkId获取道路的形状信息
        			        		LinkBean linkbean =getLinkMsg((String)traArray.getJSONObject(i).get("linkID"));
        			        		 if (null != linkbean) {
        			        			 //将有共同起点的线合成一根
        			                     lineMerger.add(linkbean.getLine());
        			                 }
        			        	}
        			        	 //合并后的线
        			        	 List<LineString> mergeList = lineMerger.getMergedLineStrings();
        			        	 for (LineString mergeLine : mergeList) {
        			        		 //对合并后的线通过起始点做垂直，进行线的截取
        			                 Coordinate aftercoord =
        			                         Tools.getVertical(mergeLine, new Coordinate(locationList.get(1).getGeometry().getCoordinates().get(0), locationList.get(1).getGeometry().getCoordinates().get(1)));
        			                 Coordinate beforecoord =
        			                		 Tools.getVertical(mergeLine, new Coordinate(locationList.get(0).getGeometry().getCoordinates().get(0), locationList.get(0).getGeometry().getCoordinates().get(1)));
        			                 try {
        			                		String gpsTimeStr1=locationList.get(0).getProperties().getTime()+"";
        			                		long gpsTime1=dateToStamp(gpsTimeStr1);
        			                		String gpsTimeStr2=locationList.get(1).getProperties().getTime()+"";
        			                		long gpsTime2=dateToStamp(gpsTimeStr2);
        			                	 	//补点操作
        			                         cutLines(beforecoord.x, beforecoord.y,gpsTime1 , aftercoord.x,
        			                                 aftercoord.y,gpsTime2, mergeLine, cutList);
        			                 } catch (ParseException e) {
        			                     e.printStackTrace();
        			                 }
        			             }
        			        	   lineMerger.clear();
        			               int flag = 0;
        			       
        			               long beforeloctime=locationList.get(0).getProperties().getTime();
        			               //补点后的线进行封装
        			               if(cutList !=null && cutList.size()>0){
	        			        	   for(int i=0;i<cutList.size();i++){
	        			        		   Coordinate[] coordinate=cutList.get(i).getCoordinates();
	        			        		   double temp=0;
	        			        		   for(int j=0;j<coordinate.length;j++){			        			   
	        			        			    JSONObject pointMsg=new JSONObject();
//	        			        			    pointMsg.put("carId",locationList.get(1).getProperties().getCar_number());
	        			        			    pointMsg.put("speed",locationList.get(1).getProperties().getSpeed());
	        			        			 
	        			        			    int seq=(int)(coordinate[j].z);
	        			        			    if(seq%leavel == 0 && seq !=60){
	        			        			        double dir=0;
		        			        			    if(j+1<coordinate.length){
			        			        			    dir=Tools.getDir(coordinate[j+1].x, coordinate[j+1].y,coordinate[j].x, coordinate[j].y);
			        			        			
				        			        			if(coordinate[j+1].x == coordinate[j+1].x && coordinate[j+1].y== coordinate[j].y && temp>=80){
			        			        			    	dir=temp;
			        			        			    }
				        			        			 temp=dir;
		        			        			    } 
		        			        			    String poointMsg= "["+ coordinate[j].x+","+coordinate[j].y+","+(seq/leavel+1)+","+dir+"]";
		        			        			    if(j == 0){
		        			        			    	 pointMsg.put("time",locationList.get(0).getProperties().getTime());
		        			        			    }
		        			        			    if(j == coordinate.length-1){
		        			        			    	pointMsg.put("time",locationList.get(1).getProperties().getTime());
		        			        			    }
	//	        			        			    pointMsg.put("dir",dir);
		        			        			    pointMsg.put("point",JSON.parseArray(poointMsg));
		        			        			    pointArray.add(pointMsg);
	        			        			    }
	        			        		   }
	        			        	   }	
        			               }else{
        			            	   for(int i=0;i<locationList.size();i++){
               	                		JSONObject pointMsg=new JSONObject();
               		        			double  dir=Tools.getDir(locationList.get(0).getGeometry().getCoordinates().get(0), locationList.get(0).getGeometry().getCoordinates().get(1), locationList.get(1).getGeometry().getCoordinates().get(0), locationList.get(1).getGeometry().getCoordinates().get(1));	
//               	          			    pointMsg.put("carId",locationList.get(i).getProperties().getCar_number());
               	          			    pointMsg.put("speed",locationList.get(i).getProperties().getSpeed());	
               	          			    pointMsg.put("time",locationList.get(i).getProperties().getTime());
               	              			String poointMsg= "["+ locationList.get(i).getGeometry().getCoordinates().get(0)+","+locationList.get(i).getGeometry().getCoordinates().get(1)+","+(i+1)+","+dir+"]";
               	              		    pointMsg.put("point",JSON.parseArray(poointMsg));
               	              			pointArray.add(pointMsg);	
                               		}
        			               }
        	        		}else{
        	        			for(int i=0;i<locationList.size();i++){
        	                		JSONObject pointMsg=new JSONObject();
        		        			double  dir=Tools.getDir(locationList.get(0).getGeometry().getCoordinates().get(0), locationList.get(0).getGeometry().getCoordinates().get(1), locationList.get(1).getGeometry().getCoordinates().get(0), locationList.get(1).getGeometry().getCoordinates().get(1));	
//        	          			    pointMsg.put("carId",locationList.get(i).getProperties().getCar_number());
        	          			    pointMsg.put("speed",locationList.get(i).getProperties().getSpeed());		
        	          			    pointMsg.put("time",locationList.get(i).getProperties().getTime());
        	              			String poointMsg= "["+ locationList.get(i).getGeometry().getCoordinates().get(0)+","+locationList.get(i).getGeometry().getCoordinates().get(1)+","+(i+1)+","+dir+"]";
        	              		    pointMsg.put("point",JSON.parseArray(poointMsg));
        	              			pointArray.add(pointMsg);	
                        		}
        	        		}
        	        	}else{
        	        		for(int i=0;i<locationList.size();i++){
    	                		JSONObject pointMsg=new JSONObject();
    		        			double  dir=Tools.getDir(locationList.get(0).getGeometry().getCoordinates().get(0), locationList.get(0).getGeometry().getCoordinates().get(1), locationList.get(1).getGeometry().getCoordinates().get(0), locationList.get(1).getGeometry().getCoordinates().get(1));	
//    	          			    pointMsg.put("carId",locationList.get(i).getProperties().getCar_number());
    	          			    pointMsg.put("speed",locationList.get(i).getProperties().getSpeed());		
    	          			    pointMsg.put("time",locationList.get(i).getProperties().getTime());
    	              			String poointMsg= "["+ locationList.get(i).getGeometry().getCoordinates().get(0)+","+locationList.get(i).getGeometry().getCoordinates().get(1)+","+(i+1)+","+dir+"]";
    	              		    pointMsg.put("point",JSON.parseArray(poointMsg));
    	              			pointArray.add(pointMsg);	
                    		}
        	        	}
        	        	}else{
        	        		for(int i=0;i<locationList.size();i++){
    	                		JSONObject pointMsg=new JSONObject();
    		        			double  dir=Tools.getDir(locationList.get(0).getGeometry().getCoordinates().get(0), locationList.get(0).getGeometry().getCoordinates().get(1), locationList.get(1).getGeometry().getCoordinates().get(0), locationList.get(1).getGeometry().getCoordinates().get(1));	
//    	          			    pointMsg.put("carId",locationList.get(i).getProperties().getCar_number());
    	          			    pointMsg.put("speed",locationList.get(i).getProperties().getSpeed());	
    	          			   pointMsg.put("time",locationList.get(i).getProperties().getTime());
    	              			String poointMsg= "["+ locationList.get(i).getGeometry().getCoordinates().get(0)+","+locationList.get(i).getGeometry().getCoordinates().get(1)+","+(i+1)+","+dir+"]";
    	              		    pointMsg.put("point",JSON.parseArray(poointMsg));
    	              			pointArray.add(pointMsg);	
                    		}
        	        	}
                	}else{
                		for(int i=0;i<locationList.size();i++){
	                		JSONObject pointMsg=new JSONObject();
		        			double  dir=Tools.getDir(locationList.get(0).getGeometry().getCoordinates().get(0), locationList.get(0).getGeometry().getCoordinates().get(1), locationList.get(1).getGeometry().getCoordinates().get(0), locationList.get(1).getGeometry().getCoordinates().get(1));	
//	          			    pointMsg.put("carId",locationList.get(i).getProperties().getCar_number());
	          			    pointMsg.put("speed",locationList.get(i).getProperties().getSpeed());	
	          			    pointMsg.put("time",locationList.get(i).getProperties().getTime());
	              			String poointMsg= "["+ locationList.get(i).getGeometry().getCoordinates().get(0)+","+locationList.get(i).getGeometry().getCoordinates().get(1)+","+(i+1)+","+dir+"]";
	              		    pointMsg.put("point",JSON.parseArray(poointMsg));
	              			pointArray.add(pointMsg);	
                		}
                	}
        			
        		}
        	}
           tp.clear();
     	   tp.put("data", pointArray);
     	   return;
        }else{
        	tp=null;
        	return;
        }
	}
	
	 /**
	     * Coordinate数组转wkt
	     * 
	     * @param geo
	     * @return
	     */
	    public static String getLineFromCoordinateSequence(String geo) {
	        StringBuilder sb = new StringBuilder();
	        String replaceAll =
	                geo.replaceAll("\\), \\(", "\\);\\(").replaceAll("\\[", "").replaceAll("\\]", "");
	        String[] coorSplit = replaceAll.split(";");
	        Coordinate[] coordinates = new Coordinate[coorSplit.length];
	        if (coordinates.length == 1) {
	            sb.append("POINT");
	        } else {
	            sb.append("LINESTRING");
	        }
	        for (int i = 0; i < coorSplit.length; i++) {
	            String[] coordinate =
	                    coorSplit[i].replaceAll("\\(", "").replaceAll("\\)", "").split(",");
	            sb.append(new Coordinate(Double.parseDouble(coordinate[0]), Double
	                    .parseDouble(coordinate[1]), Double.parseDouble(coordinate[2])).toString());
	        }
	        return sb.toString().trim().replaceAll(",", " ").replaceAll("\\)\\(", ",");
	    }
	
	/**
	 * 截取时间
	 * @param timeStr
	 * @return
	 */
    private int minuteNum(String timeStr) {
        return Integer.parseInt(timeStr.substring(0, 2));
    }
    /**
     * 时间编号
     * @param timeStr
     * @return
     */
    private int seq(String timeStr) {
        return Integer.parseInt(timeStr.substring(2));
    }
    /**
     * 获取两点间距离
     * @param lng1
     * @param lat1
     * @param lng2
     * @param lat2
     * @return
     */
    private double getDistance(double lng1, double lat1, double lng2, double lat2) {
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);
        double radLon1 = Math.toRadians(lng1);
        double radLon2 = Math.toRadians(lng2);

        if (radLat1 < 0)
            radLat1 = Math.PI / 2 + Math.abs(radLat1);// south
        if (radLat1 > 0)
            radLat1 = Math.PI / 2 - Math.abs(radLat1);// north
        if (radLon1 < 0)
            radLon1 = Math.PI * 2 - Math.abs(radLon1);// west
        if (radLat2 < 0)
            radLat2 = Math.PI / 2 + Math.abs(radLat2);// south
        if (radLat2 > 0)
            radLat2 = Math.PI / 2 - Math.abs(radLat2);// north
        if (radLon2 < 0)
            radLon2 = Math.PI * 2 - Math.abs(radLon2);// west

        double x1 = 6378137.0 * Math.cos(radLon1) * Math.sin(radLat1);
        double y1 = 6378137.0 * Math.sin(radLon1) * Math.sin(radLat1);
        double z1 = 6378137.0 * Math.cos(radLat1);

        double x2 = 6378137.0 * Math.cos(radLon2) * Math.sin(radLat2);
        double y2 = 6378137.0 * Math.sin(radLon2) * Math.sin(radLat2);
        double z2 = 6378137.0 * Math.cos(radLat2);

        double d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));

        double theta =
                Math.acos((6378137.0 * 6378137.0 + 6378137.0 * 6378137.0 - d * d)
                        / (2 * 6378137.0 * 6378137.0));
        double dist = theta * 6378137.0;
        return dist;

    }
    /**
     * 判断点是否在线上
     */
    public boolean pointOnLine(LineString line, Point point) {
        Coordinate beforecoord =
                Tools.getVertical(line, new Coordinate(point.getX(), point.getY()));

        return beforecoord.x == point.getX() && beforecoord.y == point.getY();

    }
    /**
     * 线的切割
     * @param coordinates
     * @param startP
     * @param endP
     * @return
     * @throws ParseException
     */
    private Geometry splitLinesByPoint(Coordinate[] coordinates, Point startP, Point endP)
            throws ParseException {
        int meetStart = 0;
        GeometryFactory factory = new GeometryFactory();
        ArrayList<Coordinate> lineMerger = new ArrayList<Coordinate>();
        WKTReader wktReader = new WKTReader();
        for (int i = 0; i < coordinates.length - 1; i++) {

            Coordinate[] tmp = new Coordinate[] {coordinates[i], coordinates[i + 1]};
            LineString tmpString = factory.createLineString(tmp);
            if (pointOnLine(tmpString, startP) && pointOnLine(tmpString, endP)) {
                lineMerger = new ArrayList<Coordinate>();
                lineMerger.addAll(Arrays.asList((new Coordinate[] {startP.getCoordinate(),
                        endP.getCoordinate()})));
                break;
            }
            if (pointOnLine(tmpString, startP)) {
                meetStart++;
                lineMerger.addAll(Arrays.asList((new Coordinate[] {
                        new Coordinate(startP.getCoordinate().x, startP.getCoordinate().y,
                                coordinates[i + 1].z - 1), coordinates[i + 1]})));
                continue;
            }
            if (pointOnLine(tmpString, endP)) {
                lineMerger.addAll(Arrays.asList((new Coordinate[] {
                        coordinates[i],
                        new Coordinate(endP.getCoordinate().x, endP.getCoordinate().y,
                                coordinates[i].z + 1)})));
                break;
            }
            if (meetStart > 0) {
                lineMerger.addAll(Arrays.asList((tmpString.getCoordinates())));
            }

        }
        if (lineMerger.size() == 0) {
            return null;
        }
        Geometry read = wktReader.read(getLineFromCoordinateSequence(lineMerger.toString()));
        lineMerger.clear();
        return read;
    }
    /**
     * 补点操作
     * @param blng
     * @param blat
     * @param btime
     * @param alng
     * @param alat
     * @param atime
     * @param geo
     * @param cutLineList
     * @return
     * @throws ParseException
     */
	 public List<LineString> cutLines(double blng, double blat, long btime, double alng,
	            double alat, long atime, LineString geo, List<LineString> cutLineList)
	            throws ParseException {
		    SimpleDateFormat sdf = new SimpleDateFormat("mmss");
	        String btimeStr = sdf.format(new Date(btime));
	        String atimeStr = sdf.format(new Date(atime));

	        int btimeMinute = minuteNum(btimeStr);
	        int atimeMinute = minuteNum(atimeStr);
	        long timeInterval = (atime - btime) / 1000 - 1;

	        int countAll = 0;
	        int countMid = 0;
	        if (btimeMinute != atimeMinute) {
	            int midtime = Integer.parseInt(String.valueOf(btimeMinute) + "60");
	            countMid = midtime - Integer.parseInt(btimeStr);
	        }

	        Coordinate[] coordinates = geo.getCoordinates();
	        GeometryFactory factory = new GeometryFactory();
	        Point startP = factory.createPoint(new Coordinate(blng, blat));
	        Point endP = factory.createPoint(new Coordinate(alng, alat));
	        double distanceSpfromFirstNode =
	                getDistance(startP.getX(), startP.getY(), coordinates[0].x, coordinates[0].y);
	        double distanceEpfromFirstNode =
	                getDistance(endP.getX(), endP.getY(), coordinates[0].x, coordinates[0].y);

	        if (distanceSpfromFirstNode > distanceEpfromFirstNode) {
	            Collections.reverse(Arrays.asList(coordinates));
	        }

	        Geometry splitLinesByPoint = splitLinesByPoint(coordinates, startP, endP);
	        if (splitLinesByPoint == null) {
	            return cutLineList;
	        }
	        coordinates = splitLinesByPoint.getCoordinates();

	        int lineNum = coordinates.length - 1;
	        long ratio = timeInterval / lineNum;
	        List<Coordinate> tmp2 = new ArrayList<Coordinate>();
	        // 时间段小于线段长度，需要删掉线上的点，按照斜率保留点
	        if (timeInterval < lineNum) {
	            return cutLineList;

	            // 时间段大于线段长度，需要插点
	        } else {
	            int flag2 = 1;
	            double stepLastX = 0;
	            double stepLastY = 0;
	            for (int i = 0; i < coordinates.length - 1; i++) {
	                if (timeInterval % lineNum != 0 && i == coordinates.length - 2) {
	                    ratio = timeInterval - countAll;
	                }
	                double stepx = (coordinates[i + 1].x - coordinates[i].x) / ratio;
	                double stepy = (coordinates[i + 1].y - coordinates[i].y) / ratio;
	                stepLastX = stepx;
	                stepLastY = stepy;
	                if (countMid == 0 || countAll != countMid) {
	                    if (countAll < countMid || countMid == 0) {
	                        tmp2.add(new Coordinate(new Coordinate(coordinates[i].x, coordinates[i].y,
	                                seq(btimeStr) + countAll)));
	                        countAll++;
	                    } else {
	                        if (countAll >= countMid + 60 * flag2) {
	                            flag2++;
	                        }
	                        Coordinate cutP =
	                                new Coordinate(coordinates[i].x, coordinates[i].y, seq(btimeStr)
	                                        + countAll - 60 * flag2);
	                        countAll++;
	                        tmp2.add(cutP);
	                    }
	                } else {
	                    tmp2.add(new Coordinate(new Coordinate(coordinates[i].x, coordinates[i].y, 0)));
	                    countAll++;
	                }
	                for (int j = 1; j < ratio; j++) {
	                    if (countMid == 0 || countAll != countMid) {
	                        if (countAll < countMid || countMid == 0) {
	                            Coordinate cutP =
	                                    new Coordinate(coordinates[i].x + stepx * j, coordinates[i].y
	                                            + stepy * j, seq(btimeStr) + countAll);
	                            countAll++;
	                            tmp2.add(cutP);

	                        } else {
	                            if (countAll >= countMid + 60 * flag2) {
	                                flag2++;
	                            }
	                            Coordinate cutP =
	                                    new Coordinate(coordinates[i].x + stepx * j, coordinates[i].y
	                                            + stepy * j, seq(btimeStr) + countAll - 60 * flag2);
	                            countAll++;
	                            tmp2.add(cutP);
	                        }
	                    } else {
	                        countAll++;
	                        tmp2.add(new Coordinate(coordinates[i].x + stepx * j, coordinates[i].y
	                                + stepy * j, 0));
	                    }
	                }
	            }
	            tmp2.add(new Coordinate(coordinates[coordinates.length - 2].x + ratio * stepLastX,
	                    coordinates[coordinates.length - 2].y + ratio * stepLastY, seq(btimeStr)
	                            + countAll - 60 * flag2));
	        }
	        List<Coordinate> tmp3 = new ArrayList<Coordinate>();
	        Coordinate tmp = null;
	        for (Coordinate coord : tmp2) {
	            if (coord.z == 0 && tmp3.size() != 0) {
	                tmp3.add(new Coordinate(coord.x, coord.y, tmp.z + 1));
	                LineString cutLineString =
	                        factory.createLineString(tmp3.toArray(new Coordinate[] {}));
	                cutLineList.add(cutLineString);
	                tmp3.clear();
	                tmp3.add(coord);
	            } else {
	                tmp = coord;
	                tmp3.add(coord);
	            }
	        }
	        tmp2 = null;
	        LineString cutLineString = null;
	        if (tmp3.size() == 1) {
	            Coordinate coordinate = tmp3.get(tmp3.size() - 1);
	            tmp3.add(new Coordinate(coordinate.x, addDouble(coordinate.y, 0.00001d),
	                    coordinate.z + 1));
	            cutLineString = factory.createLineString(tmp3.toArray(new Coordinate[] {}));
	        } else if (tmp3.size() > 1) {
	            cutLineString = factory.createLineString(tmp3.toArray(new Coordinate[] {}));
	        } else {
	            return cutLineList;
	        }
	        cutLineList.add(cutLineString);
	        tmp3 = null;
	        return cutLineList;
	    }
	
	
	    public double addDouble(double d, double d1) {
	        BigDecimal b1 = new BigDecimal(Double.toString(d));
	        BigDecimal b2 = new BigDecimal(Double.toString(d1));
	        return b1.add(b2).doubleValue();
	    }
	
	/**
	 * 获取link几何信息
	 * @param linkInfo
	 * @return
	 */
	public LinkBean getLinkMsg(String linkInfo) {
	    Map<String, String> linkMap= new ConcurrentHashMap<String, String>();
	    Map<String, String> noFoundLinkMap= new ConcurrentHashMap<String, String>();
        if (linkInfo.equals("null") || linkInfo.equals("") || linkInfo == null) {
            return null;
        }
        LinkInfoBean linkInfoBean = new LinkInfoBean(linkInfo);

        // key linkID
        String json = linkMap.get(linkInfoBean.getLinkId());
        if (json == null) {
            if (noFoundLinkMap.get(linkInfoBean.getLinkId()) != null) {
                return null;
            }
            String host=configBean.getHost();
            int port=configBean.getPort();
            String password=configBean.getPassword();
            int db=Integer.parseInt(configBean.getDbName());
            linkUtil.open(IOUtil.makeRedisParam(host,port,password,db));
            String queryString = linkUtil.queryString(linkInfoBean.getLinkId());
            linkUtil.close();
            if (queryString == null) {
                noFoundLinkMap.put(linkInfoBean.getLinkId(), "1");
                return null;
            }
            linkMap.put(linkInfoBean.getLinkId(), queryString);
            json = linkMap.get(linkInfoBean.getLinkId());
            if (json == null) {
                noFoundLinkMap.put(linkInfoBean.getLinkId(), "1");
                return null;
            }
            return new LinkBean(linkInfoBean.getLinkId(), json);
        } else {
            return new LinkBean(linkInfoBean.getLinkId(), json);
        }
    }
	/**
	 * HH:mm:ss
	 * @param date
	 * @return
	 */
	public static String getHMS(long timetemp) {
		Calendar calendar=Calendar.getInstance();
		calendar.setTimeInMillis(timetemp);
		SimpleDateFormat fmat=new SimpleDateFormat("HH:mm:ss");
		String time=fmat.format(calendar.getTime());
		System.out.println(time);
		return time;
	}
//	public static void main(String[] args) {
////		long l3=System.currentTimeMillis();  
////		System.out.println(l3);
////		String json="{ \"type\": \"FeatureCollection\",\"features\": [{ \"type\": \"Feature\",\"geometry\": {\"type\": \"Point\", \"coordinates\": [116.3847023, 39.9073249]},\"properties\": {\"car_number\": \"1\",\"speed\": 12.2,\"direct\": 180.0,\"time\": 1530268251780}},{ \"type\": \"Feature\",\"geometry\": {\"type\": \"Point\", \"coordinates\": [116.3826745, 39.9083906]},\"properties\": {\"car_number\": \"1\",\"speed\": 12.2,\"direct\": 180.0,\"time\": 1530268311780 }}]}";
////		JSONObject obj =(JSONObject) JSON.parse(json);
////		getHMS(Long.parseLong("1530268251780"));
////		getHMS(Long.parseLong("1530268311780"));
////		AddPointTransformImpl trans=new AddPointTransformImpl(5);
////        trans.trans(obj,5);
////        System.out.println(obj);
//		double dir=Tools.getDir(102.63666,37.92864,102.63664,37.92848);
//		 String time ="3400551028" ;
//		 timeStamp2Date(time,""); 
//	}
	  /** 
	       * 时间戳转换成日期格式字符串 
	       * @param seconds 精确到秒的字符串 
	       * @param formatStr 
	       * @return 
	      */  
	    public static String timeStamp2Date(String seconds,String format) {  
	         if(seconds == null || seconds.isEmpty() || seconds.equals("null")){  
	            return "";  
	        }  
	         if(format == null || format.isEmpty()){
	             format = "yyyy-MM-dd HH:mm:ss";
	         }   
	         SimpleDateFormat sdf = new SimpleDateFormat(format);  
	         System.out.println(sdf.format(new Date(Long.valueOf(seconds+"000"))));
	        return sdf.format(new Date(Long.valueOf(seconds+"000")));  
	     }  
	    /* 
	     * 将时间转换为时间戳
	     */    
	    public static long dateToStamp(String s) {
	    	long ts=0;
	    	try{
		        String res;
		        String dateStr=s.substring(0,4)+"-"+s.substring(4,6)+"-"+s.substring(6,8) +" "+s.substring(8,10) +":"+s.substring(10,12)+":"+s.substring(12,14);
		        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		        Date date = simpleDateFormat.parse(dateStr);
		        ts = date.getTime();
	    	}catch(Exception e){
	    		e.printStackTrace();
	    	}
	        return ts;
	    }
}
